#include "Board.h"

namespace Dicewars
{
	Board::Board()
	{
		hoveredTile = NULL;
		selectedTile = NULL;
		Box boundingBox = Box();
		model = new ColladaModel("data/board.dae", boundingBox);
		for(int i = 0; i < width; i++)
		{
			for(int k = 0; k < height; k++)
			{
				Vector2* initVector = new Vector2(i, k);
				BoardTile* currentTile = new BoardTile(initVector);
				currentTile->GetModel()->SetTranslation(i * 3.0, -1.0, k * 3.0);
				tiles[i][k] = currentTile;
			}
		}
	}
	
	Board::~Board()
	{
		for(int i = 0; i < width; i++)
		{
			for(int k = 0; k < height; k++)
			{
				delete tiles[i][k];
			}
		}
	}
	
	BoardTile* Board::GetBoardTile(unsigned int x, unsigned int y)
	{
		if(TileWithinBoardBounds(x, y))
		{
			return tiles[x][y];
		}
		else
		{
			return NULL;
		}
	}
	
	BoardTile* Board::GetSelectedTile() const
	{
		return selectedTile;
	}
	
	void Board::SetHoveredTile(BoardTile* hovered)
	{
		hoveredTile = hovered;
	}

	void Board::SetSelectedTile(BoardTile* selected)
	{
		if(selectedTile != NULL)
		{
			float previousR = selectedTile->GetModel()->GetDiffuse()[0];
			float previousG = selectedTile->GetModel()->GetDiffuse()[1];
			float previousB = selectedTile->GetModel()->GetDiffuse()[2];
			float previousA = selectedTile->GetModel()->GetDiffuse()[3];		
			selectedTile->GetModel()->SetDiffuse(previousR-1.0, previousG-0.3, previousB-0.3, previousA);
		}
		selectedTile = selected;
		if(selectedTile != NULL)
		{
			float currentR = selectedTile->GetModel()->GetDiffuse()[0];
			float currentG = selectedTile->GetModel()->GetDiffuse()[1];
			float currentB = selectedTile->GetModel()->GetDiffuse()[2];
			float currentA = selectedTile->GetModel()->GetDiffuse()[3];
			selectedTile->GetModel()->SetDiffuse(currentR+1.0, currentG+0.3, currentB+0.3, currentA);
		}
	}
	
	const bool Board::MoveAllowed(BoardTile* start, BoardTile* end) const
	{	
		if(start != NULL && end != NULL)
		{
			int startX = start->GetPosition()->x;
			int startY = start->GetPosition()->y;
			int endX = end->GetPosition()->x;
			int endY = end->GetPosition()->y;
			if(TileWithinBoardBounds(startX, startY) && TileWithinBoardBounds(startX, startY))
			{
				if(startX == endX)
				{
					if(startY == endY - 1) return true;
					if(startY == endY + 1) return true;
				}
				
				if(startY == endY)
				{
					if(startX == endX - 1) return true;
					if(startX == endX + 1) return true;
				}
			}
		}
		return false;
	}
	
	const bool Board::TileWithinBoardBounds(int x, int y) const
	{
		return(x >= 0 && x < width && y >= 0 && y < height);
	}
	
	const MoveMode Board::GetMoveMode(BoardTile* start, BoardTile* end, Player* activePlayer) const
	{
		if(start == NULL && end != NULL)
		{
			if(end->GetOwner() == activePlayer)
			{
				return Reselect;
			}
			else
			{
				return Cancel;
			}
		}
		if(end->GetOwner() == activePlayer)
		{
			return Reselect;
		}
		else if(MoveAllowed(start, end))
		{
			if(end->GetOwner() == NULL)
			{
				return MoveDice;
			}
			else
			{	
				return Attack;
			}
		}
		return Cancel;
	}
	
	const int Board::GetWidth() const
	{
		return width;
	}
	
	const int Board::GetHeight() const
	{
		return height;
	}

	unsigned int Board::CountTilesOwnedByPlayer(Player* activePlayer)
	{
		int tilecount=0;
		for(int i = 0; i < width; i++)
		{
			for(int k = 0; k < height; k++)
			{
				if(tiles[i][k]->GetOwner() != NULL)
				{
					if(tiles[i][k]->GetOwner()->GetNumber() == activePlayer->GetNumber())
					{
						tilecount++;
					}
				}
			}
		}
		return(tilecount);
	}
	
	std::vector<BoardTile*> Board::GetTilesOwnedByPlayer(Player* activePlayer) const
	{
		std::vector<BoardTile*> playerTiles;
		for(int i = 0; i < width; i++)
		{
			for(int k = 0; k < height; k++)
			{
				if(tiles[i][k]->GetOwner() != NULL)
				{
					if(tiles[i][k]->GetOwner()->GetNumber() == activePlayer->GetNumber())
					{
						playerTiles.push_back(tiles[i][k]);
					}
				}
			}
		}
		return playerTiles;
	}
	
	void Board::Draw()
	{
		model->Draw();
	}

	ColladaModel* Board::GetModel() const
	{
		return model;
	}
}
